home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / trace.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  6.1 KB  |  285 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <time.h>
  4. #include <stdarg.h>
  5. #include <conio.h>
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "iface.h"
  9. #include "trace.h"
  10. #include "pktdrvr.h"
  11. #include "commands.h"
  12. #include "session.h"
  13. #include "files.h"
  14.  
  15. static void near ascii_dump __ARGS((FILE *fp,struct mbuf **bpp));
  16. static void near hex_dump __ARGS((FILE *fp,struct mbuf **bpp));
  17.  
  18. /* Redefined here so that programs calling dump in the library won't pull
  19.  * in the rest of the package
  20.  */
  21. static char nospace[] = "No space!\n";
  22.  
  23. void
  24. dump(struct iface *iface,int direction,unsigned type,struct mbuf *bp)
  25. {
  26.     struct mbuf *tbp;
  27.     void (*func) __ARGS((FILE *,struct mbuf **,int));
  28.     int16 size;
  29.     char *cp;
  30.  
  31.     if(iface == NULLIF)
  32.         return;
  33.  
  34.     switch(direction) {
  35.     case IF_TRACE_IN:
  36.         iface->lastrecv = secclock();
  37.         iface->rawrecvcnt++;
  38.         break;
  39.     case IF_TRACE_OUT:
  40.         iface->lastsent = secclock();
  41.         iface->rawsndcnt++;
  42.         break;
  43.     }
  44.  
  45.     if((Current != Trace && iface->trfile == NULLCHAR)
  46.       || (iface->trace & direction) == 0)
  47.         return;    /* Nothing to trace */
  48.  
  49.     if(direction == IF_TRACE_IN && (iface->trace & IF_TRACE_NOBC)
  50.       && (Tracef[type].addrtest != NULLFP) && (*Tracef[type].addrtest)(iface,bp) == 0)
  51.         return;        /* broadcasts are suppressed */
  52.  
  53.     cp = ctime(&currtime);
  54.     cp[24] = '\0';
  55.  
  56.     trprintf(iface->trfp,"%s %s (%s):\n",
  57.         iface->name,(direction & IF_TRACE_OUT) ? "sent" : "recv",cp);
  58.  
  59.     if(bp == NULLBUF || (size = len_p(bp)) == 0) {
  60.         trprintf(iface->trfp,"empty packet\n");
  61.         return;
  62.     }
  63.     dup_p(&tbp,bp,0,size);
  64.  
  65.     if(tbp != NULLBUF) {
  66.         if((func = (type < NCLASS) ? Tracef[type].tracef : NULLVFP) != NULLVFP) {
  67. #ifdef MSDOS
  68.             textattr(WHITE);
  69. #endif
  70.             (*func)(iface->trfp,&tbp,1);
  71. #ifdef MSDOS
  72.                     textattr(LIGHTGRAY);
  73. #endif
  74.             if(iface->trace & IF_TRACE_ASCII)
  75.                 /* Dump only data portion of packet in ascii */
  76.                 ascii_dump(iface->trfp,&tbp);
  77.             else if(iface->trace & IF_TRACE_HEX) {
  78.                 free_p(tbp);
  79.                 dup_p(&tbp,bp,0,len_p(bp));
  80.                 /* Dump entire packet in hex/ascii */
  81.                 hex_dump(iface->trfp,&tbp);
  82.             }
  83.         } else {
  84.             trprintf(iface->trfp,"%s",nospace);
  85.         }
  86.     }
  87.     free_p(tbp);
  88. }
  89.  
  90. /* Convert byte to two ascii-hex characters */
  91. static void near
  92. ctohex(char *buf,int16 c)
  93. {
  94.     static char hex[] = "0123456789abcdef";
  95.  
  96.     *buf++ = hex[hinibble(c)];
  97.     *buf = hex[lonibble(c)];
  98. }
  99.  
  100. /* Print a buffer up to 16 bytes long in formatted hex with ascii
  101.  * translation, e.g.,
  102.  * 0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f  0123456789:;<=>?
  103.  */
  104. static void near
  105. fmtline(FILE *fp,int16 addr,char *buf,int16 len)
  106. {
  107.     char line[80];
  108.     char *aptr, *cptr, c;
  109.  
  110.     memset(line,' ',sizeof(line));
  111.     ctohex(line,(int16)hibyte(addr));
  112.     ctohex(line+2,(int16)lobyte(addr));
  113.     aptr = &line[6];
  114.     cptr = &line[55];
  115.     while(len-- != 0){
  116.         c = *buf++;
  117.         ctohex(aptr,(int16)uchar(c));
  118.         aptr += 3;
  119.         c &= 0x7f;
  120.         *cptr++ = isprint(uchar(c)) ? c : '.';
  121.     }
  122.     *cptr++ = '\n';
  123.     *cptr++ = '\0';
  124.     trprintf(fp,"%s",line);
  125. }
  126.  
  127. /* Dump an mbuf in hex */
  128. static void near
  129. hex_dump(FILE *fp,struct mbuf **bpp)
  130. {
  131.     int16 n, address = 0;
  132.     char buf[16];
  133.  
  134.     if(bpp == NULLBUFP || *bpp == NULLBUF)
  135.         return;
  136.  
  137.     while((n = pullup(bpp,buf,sizeof(buf))) != 0){
  138.         fmtline(fp,address,buf,n);
  139.         address += n;
  140.     }
  141. }
  142.  
  143. /* Dump an mbuf in ascii */
  144. static void near
  145. ascii_dump(FILE *fp,struct mbuf **bpp)
  146. {
  147.     char *cp, buf[80];
  148.     unsigned char c, cc, len;
  149.  
  150.     if(bpp == NULLBUFP || *bpp == NULLBUF)
  151.         return;
  152.  
  153.     while((len = pullup(bpp,buf,sizeof(buf))) != 0) {
  154.         cp = buf;
  155.         while(len-- != 0) {
  156.             cc = c = uchar(*cp);
  157.             *cp++ = (c == 13) ? '\n' : (c < 0x20) ? '∙' : c;
  158.         }
  159.         *cp++ = '\0';
  160.         trprintf(fp,"%s",buf);
  161.     }
  162.     if(cc != 13)
  163.         trprintf(fp,"\n");
  164. }
  165.  
  166. static void near
  167. d_trace(struct iface *ifp)
  168. {
  169.     tprintf("%s:",ifp->name);
  170.  
  171.     if(ifp->port){
  172.       tputs(" Trace on master iface only");
  173.     } else {
  174.         if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT | IF_TRACE_RAW)){
  175.             if(ifp->trace & IF_TRACE_IN)
  176.                 tputs(" input");
  177.             if(ifp->trace & IF_TRACE_OUT)
  178.                 tputs(" output");
  179.             if(ifp->trace & IF_TRACE_NOBC)
  180.                 tputs(" - no broadcasts");
  181.             if(ifp->trace & IF_TRACE_HEX)
  182.                 tputs(" (Hex/ASCII dump)");
  183.             else if(ifp->trace & IF_TRACE_ASCII)
  184.                 tputs(" (ASCII dump)");
  185.             else
  186.                 tputs(" (headers only)");
  187.             if(ifp->trace & IF_TRACE_RAW)
  188.                 tputs(" Raw output");
  189.             if(ifp->trfile != NULLCHAR)
  190.                 tprintf(" trace file: %s",ifp->trfile);
  191.         } else {
  192.             tputs(" tracing off");
  193.         }
  194.     }
  195.     tputs("\n");
  196. }
  197.  
  198. /* Modify or displace interface trace flags */
  199. int
  200. dotrace(int argc,char *argv[],void *p)
  201. {
  202.     struct iface *ifp;
  203.  
  204.     if(argc < 2){
  205.         for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  206.             d_trace(ifp);
  207.     } else {
  208.         if((ifp = if_lookup(argv[1])) == NULLIF){
  209.             tprintf(Badif,argv[1]);
  210.             return 1;
  211.         }
  212.         if(argc == 2) {
  213.             d_trace(ifp);
  214.             return 0;
  215.         }
  216.         if(argc >= 3)
  217.             ifp->trace = htoi(argv[2]);
  218.  
  219.         /* Always default to stdout unless trace file is given */
  220.         if(ifp->trfp != NULLFILE && ifp->trfp != stdout)
  221.             fclose(ifp->trfp);
  222.         ifp->trfp = stdout;
  223.         if(ifp->trfile != NULLCHAR)
  224.             xfree(ifp->trfile);
  225.         ifp->trfile = NULLCHAR;
  226.  
  227.         if(argc >= 4){
  228.             if((ifp->trfp = open_file(argv[3],APPEND_TEXT,0,1)) == NULLFILE){
  229.                 ifp->trfp = stdout;
  230.             } else {
  231.                 ifp->trfile = strxdup(argv[3]);
  232.             }
  233.         }
  234.     }
  235.     return 0;
  236. }
  237.  
  238. /* shut down all trace files */
  239. void
  240. shuttrace(void)
  241. {
  242.     struct iface *ifp;
  243.  
  244.     for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next){
  245.         if(ifp->trfp != NULLFILE && ifp->trfp != stdout)
  246.             fclose(ifp->trfp);
  247.         if(ifp->trfile != NULLCHAR)
  248.             xfree(ifp->trfile);
  249.         ifp->trfile = NULLCHAR;
  250.         ifp->trfp = NULLFILE;
  251.     }
  252. }
  253.  
  254. int
  255. trprintf(FILE *fp,char *fmt,...)
  256. {
  257.     va_list ap;
  258.     char tmp[LINELEN];        /* DB3FL */
  259.     int len = 0;
  260.  
  261.     va_start(ap,fmt);
  262.     vsprintf(tmp,fmt,ap);
  263.     va_end(ap);
  264.  
  265.     if(fp != 0 && fp != stdout)
  266.         fputs(tmp,fp);
  267.     if (Current == Trace) {
  268.         char *cp = tmp;
  269.         for (;*cp;cp++) {
  270.             switch (*cp) {
  271.                 case '\r':
  272.                     continue;
  273.                 case '\n':
  274.                     putch('\r');
  275.                     putch('\n');
  276.                     len++;
  277.                     continue;
  278.                 }
  279.             putch(*cp);
  280.             len++;
  281.             }
  282.     }
  283.     return len;
  284. }
  285.